﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32;
using System.Xml;
using System.ServiceModel;
using System.Globalization;
using SPVisualDev.Services;
using SPVisualDev.VSAddin.Dialogs;
using EnvDTE;
using EnvDTE80;
using SPVisualDev.VSAddin.Services;

namespace SPVisualDev.VSAddin.UserControls
{
    public delegate void ObjectSelectedEventHandler(IExplorerObjectContainer container, object SelectedObject);

    public partial class UCSPExplorer : UserControl
    {
        private DTE2 m_dte;
        private object m_last_selected_object;
        private MainServiceWrapper m_main_svc;
        private bool m_top_node_init;
        private bool m_top_node_loading;
        private List<ProjectFeature> m_project_features;
        private ConnectionDetailsStruct m_connection_details;
        private DebugHelper m_debug_helper;

        public event ObjectSelectedEventHandler ObjectSelected;

        public UCSPExplorer()
        {
            InitializeComponent();

            tvwSPExplorer.BeforeExpand += new TreeViewCancelEventHandler(tvwSPExplorer_BeforeExpand);
            tvwSPExplorer.AfterSelect += new TreeViewEventHandler(tvwSPExplorer_AfterSelect);
        }

        private IMainService ServiceProxy
        {
            get
            {
                if (this.CurrentProject == null)
                {
                    return m_main_svc.ServiceProxy;
                }
                else
                {
                    return this.CurrentProject.ServiceProxy;
                }
            }
        }

        public bool HasContent()
        {
            return (this.tvwSPExplorer.Nodes.Count > 0) ;
        }

        /// <summary>
        /// Initializes explorer
        /// </summary>
        /// <param name="DTEObject"></param>
        /// <param name="specialProject"></param>
        /// <param name="Mode">0 = Auto, 1 = Use global settings, 2 = Use manual settings</param>
        public void InitExplorer(DTE2 DTEObject, SpecialProject specialProject, int Mode)
        {
            try
            {
                m_dte = DTEObject;

                if (m_debug_helper == null)
                    m_debug_helper = new DebugHelper(m_dte);

                if (m_top_node_loading)
                    return;


                m_top_node_loading = true;

                this.CurrentProject = specialProject;

                EnumerateProjectFeatures();

                tvwSPExplorer.ShowPlusMinus = true;
                tvwSPExplorer.ImageList = imgSPExplorerImages;
                tvwSPExplorer.TreeViewNodeSorter = new SPExplorerComparer();

                tvwSPExplorer.Nodes.Clear();

                if (m_main_svc != null)
                {
                    m_main_svc.Dispose();
                }

                m_top_node_init = false;

                if (specialProject == null)
                {
                    ConnectionDetailsStruct connectionDetails;

                    if (Mode == 1)
                    {
                        connectionDetails = Common.GetServiceConnection(null);
                    }
                    else
                    {
                        connectionDetails = new ConnectionDetailsStruct();

                        if (!string.IsNullOrEmpty(this.RemoteServerAddress))
                        {
                            connectionDetails.Address = this.RemoteServerAddress;
                            connectionDetails.Port = this.RemoteServerPort;
                        }
                        else
                        {
                            connectionDetails.Address = "";
                            connectionDetails.Port = Common.C_WCF_MAIN_SVC_PORT;

                            if (!Connect.S_Client_Install)
                                if (!SharePointLibrary.CheckIf32bitOn64())
                                    connectionDetails.UseInProc = true;
                        }
                    }

                    m_connection_details = connectionDetails;

                    try
                    {
                        this.Cursor = Cursors.WaitCursor;

                        m_main_svc = new MainServiceWrapper(m_connection_details, true);
                    }
                    finally
                    {
                        this.Cursor = Cursors.Default;
                    }
                }
                else
                {
                    m_connection_details = specialProject.RemoteConnection;
                    m_main_svc = null;
                }

                string init_txt = "Connecting to " + m_connection_details.Address;


                this.RemoteServerAddress = m_connection_details.Address;
                this.RemoteServerPort = m_connection_details.Port;

                try
                {
                    this.Cursor = Cursors.WaitCursor;

                    tvwSPExplorer.BeginUpdate();

                    tvwSPExplorer.TopNode = tvwSPExplorer.Nodes.Add(null, init_txt);
                    tvwSPExplorer.TopNode.Name = null;

                    tvwSPExplorer.TopNode.Tag = new ExFarm();

                    tvwSPExplorer.TopNode.ImageKey = string.Empty;
                    tvwSPExplorer.TopNode.SelectedImageKey = string.Empty;
                    tvwSPExplorer.TopNode.Nodes.Add(string.Empty);

                    BuildFarmContextMenu();

                    tvwSPExplorer.TopNode.Expand();
                    tvwSPExplorer.EndUpdate();

                }
                finally
                {
                    this.Cursor = Cursors.Default;
                }
            }
            catch
            {
                tvwSPExplorer.Nodes.Clear();
                tvwSPExplorer.Refresh();

                throw;
            }
            finally
            {
                m_top_node_loading = false;
            }
        }

        public int ViewType
        {
            get;
            set;
        }

        private void BuildFarmContextMenu()
        {
            if (this.SPExplorer.TopNode.ContextMenu == null)
                this.SPExplorer.TopNode.ContextMenu = new ContextMenu();

            MenuItem item = new MenuItem("Recycle all application pools");
            item.Name = "RecycleAllAppPools";
            item.Click += new EventHandler(onContextMenuClick);

            this.SPExplorer.TopNode.ContextMenu.MenuItems.Add(item);
        }

        private void BuildBrowseToURLContextMenu(TreeNode node)
        {
            IExplorerObjectContainer container = node.Tag as IExplorerObjectContainer;
            if (container.BrowseToURLs != null)
            {
                if (container.BrowseToURLs.Count > 0)
                {
                    if (node.ContextMenu == null)
                        node.ContextMenu = new ContextMenu();

                    MenuItem item = new MenuItem("Browse");
                    item.Name = "Browse";
                    node.ContextMenu.MenuItems.Add(item);


                    foreach (KeyValuePair<string, Uri> kvp in container.BrowseToURLs)
                    {
                        MenuItem subItem = new MenuItem(kvp.Key);
                        subItem.Name = kvp.Value.ToString();
                        subItem.Click += new EventHandler(subItem_Click);

                        item.MenuItems.Add(subItem);
                    }
                }
            }

        }

        private void BuildSPWebApplicationContextMenu(TreeNode node)
        {
            if (node.ContextMenu == null)
                node.ContextMenu = new ContextMenu();

            MenuItem item = new MenuItem("Recycle application pool");
            item.Name = "RecycleAppPool";
            item.Tag = (node.Tag as ExWebApplication).Url;
            item.Click += new EventHandler(onContextMenuClick);

            node.ContextMenu.MenuItems.Add(item);
        }

        private void BuildDebugContextMenu(TreeNode node)
        {
            string url = null;
            if (node.Tag is ExWebApplication)
                url = (node.Tag as ExWebApplication).Url;

            else if (node.Tag is ExSite)
                url = (node.Tag as ExSite).Url;

            else if (node.Tag is ExWeb)
                url = (node.Tag as ExWeb).Url;

            if (url == null)
                return;


            if (node.ContextMenu == null)
                node.ContextMenu = new ContextMenu();

            MenuItem item = new MenuItem("Debug");
            item.Name = "Debug";

            node.ContextMenu.MenuItems.Add(item);

            MenuItem subItem = new MenuItem("This location");
            subItem.Name = "DebugLocation";
            subItem.Tag = url;
            subItem.Click += new EventHandler(onContextMenuClick);
            
            item.MenuItems.Add(subItem);


            subItem = new MenuItem("With active page");
            subItem.Name = "DebugActivePage";
            subItem.Tag = url;
            subItem.Click += new EventHandler(onContextMenuClick);

            item.MenuItems.Add(subItem);


        }

        private void BuildGeneralContextMenu(TreeNode node)
        {
            if (node.Tag is IExplorerObjectContainer)
                BuildBrowseToURLContextMenu(node);

            if (node.ContextMenu == null)
                node.ContextMenu = new ContextMenu();

            MenuItem item = new MenuItem("Refresh");
            item.Name = "Refresh";
            item.Tag = node;
            item.Click += new EventHandler(onContextMenuClick);

            node.ContextMenu.MenuItems.Add(item);

        }

        //Type: 1 = Activate, 2 = Deactivate
        private void BuildFeaturesMenu(TreeNode node, int Type)
        {
            if (node.ContextMenu == null)
                node.ContextMenu = new ContextMenu();

            MenuItem item = new MenuItem();
            if (node.Tag is ExFeature)
            {
                item.Text = (Type == 1) ? "Deactivate feature" : "Activate feature";
                item.Name = (Type == 1) ? "Deactivate" : "Activate";
                item.Tag = node.Tag;
                item.Click += new EventHandler(subItem_Click);
            }
            else
            {
                return;


                /*
                item.Text = (Type == 1) ? "Activate project feature" : "Deactivate project feature";
                item.Name = item.Text;
                item.Tag = null;

                foreach (ProjectFeature pf in m_project_features)
                {
                    Type t = node.Tag.GetType();

                    if (pf.Scope == "Farm" && t == typeof(ExFarm))
                    {
                        item.Tag = "Farm";
                    }
                    if (pf.Scope == "WebApplication" && t == typeof(ExWebApplication))
                    {
                        item.Tag = (node.Tag as ExWebApplication).Url;
                    }
                    else if (pf.Scope == "Site" && t == typeof(ExSite))
                    {
                        item.Tag = (node.Tag as ExSite).Url;
                    }
                    else if (pf.Scope == "Web" && t == typeof(ExWeb))
                    {
                        item.Tag = (node.Tag as ExWeb).Url;
                    }

                    if (item.Tag != null)
                    {
                        MenuItem subItem = new MenuItem(pf.Name);
                        subItem.Click += new EventHandler(subItem_Click);

                        item.MenuItems.Add(subItem);
                    }
                }*/

                if (item.MenuItems.Count == 0)
                    item.MenuItems.Add("(no features available)");
            }

            node.ContextMenu.MenuItems.Add(item);
        }

        private void subItem_Click(object sender, EventArgs e)
        {
            try
            {
                MenuItem item = sender as MenuItem;

                if (item.Parent.Name == "Browse")
                {
                    Common.LaunchBrowser(item.Name);
                }

                else if (item.Tag is ExFeature)
                {
                    ExFeature feature = item.Tag as ExFeature;
                    string url = feature.ParentUrl;

                    if (item.Name == "Activate")
                    {
                        this.ServiceProxy.ActivateFeature(feature.Name, url, false);
                    }
                    else if (item.Name == "Deactivate")
                    {
                        this.ServiceProxy.DeactivateFeature(feature.Name, url, false);
                    }

                    RefreshNode(item.GetContextMenu().MenuItems["Refresh"].Tag as TreeNode);
                }

                else
                {
                    string url = item.Parent.Tag as string;

                    if (item.Parent.Name == "Activate project feature")
                    {
                        this.ServiceProxy.ActivateFeature(item.Text, url, false);
                    }
                    else if (item.Parent.Name == "Deactivate project feature")
                    {
                        this.ServiceProxy.DeactivateFeature(item.Text, url, false);
                    }

                    RefreshNode(item.GetContextMenu().MenuItems["Refresh"].Tag as TreeNode);
                }
            }
            catch(Exception ex)
            {
                DialogError.ShowError(ex);
            }
        }

        private void onContextMenuClick(object sender, EventArgs e)
        {
            try
            {
                MenuItem item = sender as MenuItem;

                if (item.Name == "RecycleAllAppPools")
                {
                    if (this.ServiceProxy != null)
                    {
                        try
                        {
                            this.ServiceProxy.RecycleIISAppPools(null);
                        }
                        catch (Exception ex)
                        {
                            DialogError.ShowError(ex);
                            return;
                        }
                    }
                    else
                    {
                        IIS.RecycleIISAppPool(null);
                    }
                }

                else if (item.Name == "RecycleAppPool")
                {
                    string url = item.Tag.ToString();
                    if (this.ServiceProxy != null)
                    {
                        try
                        {
                            this.ServiceProxy.RecycleIISAppPools(url);
                        }
                        catch (Exception ex)
                        {
                            DialogError.ShowError(ex);
                            return;
                        }
                    }
                    else
                    {
                        IIS.RecycleIISAppPool(url);
                    }
                }

                else if (item.Name == "Refresh")
                {
                    RefreshNode(item.Tag as TreeNode);
                }

                else if (item.Name == "DebugLocation")
                {
                    if (this.CurrentProject != null)
                        this.CurrentProject.SetUserSettingsValue("DebugTargetURL", item.Tag as string, true);

                    m_debug_helper.AttachDebugger(this.ServiceProxy, null, item.Tag as string, true);
                }

                else if (item.Name == "DebugActivePage")
                {
                    ProjectItem pageItem = null;
                    try
                    {
                        pageItem = m_dte.ActiveDocument.ProjectItem;
                    }
                    catch { }

                    string BaseURL = item.Tag as string;

                    m_debug_helper.AttachDebugger(this.CurrentProject, pageItem, BaseURL);
                }
            }
            catch (Exception ex)
            {
                DialogError.ShowError(ex);
            }
        }

        private void tvwSPExplorer_AfterSelect(object sender, TreeViewEventArgs e)
        {
            try
            {
                if (e.Action == TreeViewAction.Unknown)
                    return;

                if (e.Node == null)
                    return;

                if (m_last_selected_object != null)
                {
                    if (m_last_selected_object is IDisposable)
                    {
                        (m_last_selected_object as IDisposable).Dispose();
                    }
                }

                if (e.Node.Tag is IExplorerObjectContainer)
                {
                    IExplorerObjectContainer obj = e.Node.Tag as IExplorerObjectContainer;

                    if (obj == null)
                        return;

                    if (this.ServiceProxy != null)
                    {
                        m_last_selected_object = this.ServiceProxy.GetProperties(obj);
                    }
                    else
                    {
                        m_last_selected_object = Navigation.GetProperties(obj, true);
                    }

                    if (ObjectSelected != null)
                        ObjectSelected(obj, m_last_selected_object);
                }

            }
            catch (Exception ex)
            {
                DialogError.ShowError(ex);
            }
        }

        public TreeView SPExplorer
        {
            get { return tvwSPExplorer; }
        }

        public string SelectedUrl
        {
            get
            {
                if (tvwSPExplorer.SelectedNode != null && tvwSPExplorer.SelectedNode.Tag is IExplorerUrlContainer)
                    return (tvwSPExplorer.SelectedNode.Tag as IExplorerUrlContainer).Url;
                else
                    return string.Empty;
            }
        }

        public string SelectedTitle
        {
            get { return this.SPExplorer.SelectedNode.Text; }
        }

        public string SelectedContentTypeId
        {
            get
            {
                if (tvwSPExplorer.SelectedNode == null)
                    return null;

                if (tvwSPExplorer.SelectedNode.Tag is ExContentType)
                {
                    ExContentType ct = tvwSPExplorer.SelectedNode.Tag as ExContentType;

                    return ct.ID;
                }
                else
                {
                    return null;
                }
            }
        }

        public XmlNode SelectedContentType
        {
            get
            {
                if (tvwSPExplorer.SelectedNode == null)
                    return null;

                if (tvwSPExplorer.SelectedNode.Tag is ExContentType)
                {
                    ExContentType ct = tvwSPExplorer.SelectedNode.Tag as ExContentType;

                    XmlDocument xmldoc = new XmlDocument();
                    if (this.ServiceProxy != null)
                    {
                        xmldoc.LoadXml(this.ServiceProxy.GetContentTypesData(ct.ParentUrl, ct.Title));
                    }
                    else
                    {
                        xmldoc.LoadXml(ContentTypes.GetContentTypesData(ct.ParentUrl, ct.Title));
                    }

                    return xmldoc.DocumentElement;
                }
                else
                {
                    return null;
                }
            }
        }

        public string RemoteServerAddress
        {
            get;
            set;
        }

        public int RemoteServerPort
        {
            get;
            set;
        }

        public string RemoteServerUserName
        {
            get;
            set;
        }

        public string RemoteServerPassword
        {
            get;
            set;
        }


        public bool ShowSiteCollections = true;
        public bool ShowWebs = true;
        public bool ShowLists = true;
        public bool ShowListFolders = true;
        public bool ShowListItems = true;
        public bool ShowContentTypes = true;
        public bool ShowContentTypeGroups = true;
        public bool ShowFeatures = true;
        public bool ShowSolutions = true;
        public bool ShowFields = true;

        public SpecialProject CurrentProject
        {
            get;
            set;
        }

        public void EnumerateProjectFeatures()
        {
            m_project_features = new List<ProjectFeature>();

            ProjectItem features_folder = null;
            try
            {
                features_folder = this.CurrentProject.Project.ProjectItems.Item("12").ProjectItems.Item("TEMPLATE").ProjectItems.Item("Features");
            }
            catch
            {
            }

            if (features_folder == null)
                return;

            foreach (ProjectItem feature in features_folder.ProjectItems)
            {
                ProjectItem feature_xml = null;
                try
                {
                    feature_xml = feature.ProjectItems.Item("feature.xml");
                }
                catch
                {
                }

                if (feature_xml == null)
                    continue;

                try
                {
                    XmlDocument xmldoc = new XmlDocument();
                    xmldoc.Load(Common.GetProjectItemPath(feature_xml));

                    ProjectFeature pf = new ProjectFeature();
                    pf.ID = new Guid(Common.GetXmlAttribute(xmldoc.DocumentElement, "ID").ToUpper());
                    pf.Name = feature.Name;
                    pf.Scope = Common.GetXmlAttribute(xmldoc.DocumentElement, "Scope");

                    m_project_features.Add(pf);
                }
                catch(Exception ex)
                {
                    DialogError.ShowError(ex);
                }

            }
        }

        public bool DisableContextMenus
        {
            get;
            set;
        }

        public void RefreshNode(TreeNode n)
        {
            while (n.Nodes.Count > 0)
                n.Nodes.RemoveAt(0);

            RenderNode(n);
        }

        private void tvwSPExplorer_BeforeExpand(object sender, TreeViewCancelEventArgs e)
        {
            try
            {
                if (e.Action == TreeViewAction.Expand)
                    RenderNode(e.Node);
            }
            catch (Exception ex)
            {
                DialogError.ShowError(ex);
            }
        }

        private void GetChildren(TreeNode ParentNode)
        {
            bool hasNoSubGroups = (ParentNode.Tag is IExplorerObjectContainer && (ParentNode.Tag as IExplorerObjectContainer).GetSubGroups() == null);
            
            if (ParentNode.Tag is string || hasNoSubGroups)
            {
                List<IExplorerObjectContainer> list;

                IExplorerObjectContainer parent;
                if (hasNoSubGroups)
                {
                    parent = ParentNode.Tag as IExplorerObjectContainer;
                }
                else
                {
                    parent = ParentNode.Parent.Tag as IExplorerObjectContainer;
                }

                if (this.ServiceProxy != null)
                {
                    list = this.ServiceProxy.GetChildren(parent, ParentNode.Tag as string);
                }
                else
                {
                    list = Navigation.GetChildren(parent, ParentNode.Tag as string);
                }

                if (list == null || list.Count == 0)
                    return;

                foreach (IExplorerObjectContainer container in list)
                {
                    TreeNode node = ParentNode.Nodes.Add(container.Title);
                    node.Tag = container;

                    if (!this.DisableContextMenus)
                    {
                        BuildGeneralContextMenu(node);
                        BuildDebugContextMenu(node);
                    }


                    if (container.GetType() == typeof(ExWebApplication))
                    {
                        node.ImageKey = "WebApplication";
                        node.SelectedImageKey = "WebApplication";

                        if (!this.DisableContextMenus)
                        {
                            BuildFeaturesMenu(node, 1);
                            BuildFeaturesMenu(node, 2);

                            BuildSPWebApplicationContextMenu(node);
                        }
                    }
                    else if (container.GetType() == typeof(ExSite))
                    {
                        node.ImageKey = "Site";
                        node.SelectedImageKey = "Site";

                        if (!this.DisableContextMenus)
                        {
                            BuildFeaturesMenu(node, 1);
                            BuildFeaturesMenu(node, 2);
                        }
                    }
                    else if (container.GetType() == typeof(ExWeb))
                    {
                        node.ImageKey = "Web";
                        node.SelectedImageKey = "Web";

                        if (!this.DisableContextMenus)
                        {
                            BuildFeaturesMenu(node, 1);
                            BuildFeaturesMenu(node, 2);
                        }
                    }
                    else if (container.GetType() == typeof(ExList))
                    {
                        node.ImageKey = "List";
                        node.SelectedImageKey = "List";
                    }


                    else if (container.GetType() == typeof(ExContentType))
                    {
                        node.ImageKey = "ContentType";
                        node.SelectedImageKey = "ContentType";
                    }
                    else if (container.GetType() == typeof(ExField))
                    {
                        node.ImageKey = "Field";
                        node.SelectedImageKey = "Field";
                    }
                    else if (container.GetType() == typeof(ExFeature))
                    {
                        node.ImageKey = "Feature";
                        node.SelectedImageKey = "Feature";

                        if (!this.DisableContextMenus)
                        {
                            if ((node.Parent.Tag as ExFeaturesCollection).Title == "Activated")
                                BuildFeaturesMenu(node, 1);
                            else
                                BuildFeaturesMenu(node, 2);
                        }
                    }
                    else if (container.GetType() == typeof(ExFeaturesCollection))
                    {
                        node.ImageKey = container.Title;
                        node.SelectedImageKey = container.Title;
                    }
                    else if (container.GetType() == typeof(ExEventReceiver))
                    {
                        node.ImageKey = "EventReceiver";
                        node.SelectedImageKey = "EventReceiver";
                    }
                    else
                    {
                        node.ImageKey = "Folder";
                        node.SelectedImageKey = "Folder";
                    }


                    if (container.CanHaveChildren)
                        node.Nodes.Add(string.Empty);
                }
            }
            else if (ParentNode.Tag is IExplorerObjectContainer)
            {
                List<string> list;

                if (this.ServiceProxy != null)
                {
                    list = this.ServiceProxy.GetSubGroups(ParentNode.Tag as IExplorerObjectContainer);
                }
                else
                {
                    list = Navigation.GetSubGroups(ParentNode.Tag as IExplorerObjectContainer);
                }

                if (list == null || list.Count == 0)
                    return;

                foreach (string group in list)
                {
//                    TreeNode node = ParentNode.Nodes.Add(group);
                    TreeNode node = new TreeNode(group);
                    node.Tag = group;

                    if (!this.DisableContextMenus)
                    {
                        BuildGeneralContextMenu(node);
                    }

                    if (group == "Web applications")
                    {
                        node.ImageKey = "WebApplication";
                        node.SelectedImageKey = "WebApplication";
                        node.Nodes.Add(string.Empty);

                        ParentNode.Nodes.Add(node);
                    }
                    else if (group == "Sites" && this.ShowSiteCollections)
                    {
                        node.ImageKey = "Site";
                        node.SelectedImageKey = "Site";
                        node.Nodes.Add(string.Empty);

                        ParentNode.Nodes.Add(node);
                    }
                    else if (group == "Webs" && this.ShowWebs)
                    {
                        node.ImageKey = "Web";
                        node.SelectedImageKey = "Web";
                        node.Nodes.Add(string.Empty);

                        ParentNode.Nodes.Add(node);
                    }
                    else if (group == "Lists" && this.ShowLists)
                    {
                        node.ImageKey = "List";
                        node.SelectedImageKey = "List";
                        node.Nodes.Add(string.Empty);

                        ParentNode.Nodes.Add(node);
                    }


                    else if (group.EndsWith(" features") && this.ShowFeatures)
                    {
                        node.ImageKey = "Feature";
                        node.SelectedImageKey = "Feature";
                        node.Nodes.Add(string.Empty);

                        ParentNode.Nodes.Add(node);
                    }
                    else if (group == "Content types" && this.ShowContentTypes)
                    {
                        node.Nodes.Add(string.Empty);
                        ParentNode.Nodes.Add(node);
                    }
                    else if (group == "Fields" && this.ShowFields)
                    {
                        node.Nodes.Add(string.Empty);
                        ParentNode.Nodes.Add(node);
                    }
                    else if (group == "Solutions" && this.ShowSolutions)
                    {
                        node.Nodes.Add(string.Empty);
                        ParentNode.Nodes.Add(node);
                    }
                }
            }

        }

        private void RenderNode(TreeNode n)
        {
            try
            {
                if (n.Tag == null)
                    return;

                this.Cursor = Cursors.WaitCursor;

                if (n.Nodes.Count == 1)
                {
                    if (n.Nodes[0].Text == string.Empty)
                        n.Nodes.RemoveAt(0);
                }

                if (n.Nodes.Count > 0)
                    return;

                try
                {
                    SPExplorer.BeginUpdate();

                    GetChildren(n);

                    if (!m_top_node_init)
                    {
                        m_top_node_init = true;

                        n.Text = string.IsNullOrEmpty(m_connection_details.Address) ? "Local" : m_connection_details.Address;
                    }
                }
                finally
                {
                    SPExplorer.EndUpdate();
                }

            }
            catch (Exception ex)
            {
                this.Cursor = Cursors.Default;
                DialogError.ShowError(ex);
            }
            finally
            {

                this.Cursor = Cursors.Default;
            }
        }

        private struct ProjectFeature
        {
            public string Name;
            public Guid ID;
            public string Scope;
        }

        private class SPExplorerComparer : IComparer
        {
            public int Compare(object x, object y)
            {
                TreeNode nodeX = x as TreeNode;
                TreeNode nodeY = y as TreeNode;

                return string.Compare(nodeX.Text, nodeY.Text, true);
            }
        }
    }


}
